package top.boycharse.talker.factory;

import com.google.common.base.Strings;
import org.hibernate.Session;
import top.boycharse.talker.bean.db.User;
import top.boycharse.talker.utils.Hib;
import top.boycharse.talker.utils.TextUtil;

import java.util.List;
import java.util.UUID;

public class UserFactory {

    public static User findByToken(String token) {
        return Hib.query(new Hib.Query<User>() {
            @Override
            public User query(Session session) {
                return (User) session.createQuery("from User  where  token=:token")
                        .setParameter("token", token)
                        .uniqueResult();
            }
        });
    }

    public static User findByPhone(String phone) {
        return Hib.query(new Hib.Query<User>() {
            @Override
            public User query(Session session) {
                return (User) session.createQuery("from User  where  phone=:inPhone")
                        .setParameter("inPhone", phone)
                        .uniqueResult();
            }
        });
    }

    public static User findByName(String name) {
        return Hib.query(new Hib.Query<User>() {
            @Override
            public User query(Session session) {
                return (User) session.createQuery("from User  where  name=:name")
                        .setParameter("name", name)
                        .uniqueResult();
            }
        });
    }

    public static User bindPushId(User user, String pushId) {
        // 第一步，查询是否有其他账户绑定了这个设备
        // 取消绑定，避免推送错乱
        Hib.queryOnly(session -> {
            @SuppressWarnings("unchecked")
            List<User> userList = session
                    .createQuery("from User  where  lower(pushId)=:pushId and id!=:userId")
                    .setParameter("pushId", pushId.toLowerCase())
                    .setParameter("userId", user.getId())
                    .list();

            for (User u : userList) {
                u.setPushId(null);
                session.saveOrUpdate(u);
            }
        });

        if (pushId.equalsIgnoreCase(user.getPushId())) {
            return user;
        }else {
            if (!Strings.isNullOrEmpty(user.getPushId())) {
                // TODO 推送一个退出消息
            }

            user.setPushId(pushId);
            return Hib.query(session -> {
                session.saveOrUpdate(user);
                return user;
            });
        }
    }

    public static User login(String account, String password) {
        String accountStr = account.trim();
        String encodePassword = encodePassword(password);
        User user =  Hib.query(session -> {
            return (User) session.createQuery("from User where phone=:phone and password=:password")
                    .setParameter("phone", accountStr)
                    .setParameter("password", encodePassword)
                    .uniqueResult();
            }
        );
        if (user != null) {
            user = login(user);
        }

        return user;
    }

    /**
     * 注册，将用户信息插入数据库
     * @param account 手机号
     * @param password 密码
     * @param name 姓名
     * @return User
     */
    public static User register(String account, String password, String name) {

        //去除多余空格
        account = account.trim();
        //对密码进行加密，然后再存入数据库
        password = encodePassword(password);
        User user = createUser(account,password,name);

        if (user != null) {
            user = login(user);
        }

        return user;
    }

    private static User login(User user) {
        // 使用一个随机的UUID值充当token
        String newToken = UUID.randomUUID().toString();

        newToken = TextUtil.encodeBase64(newToken);
        user.setToken(newToken);
        return update(user);
    }

    private static User createUser(String account, String password, String name) {
        User user = new User();
        user.setName(name);
        user.setPassword(password);
        user.setPhone(account);

        return Hib.query(session -> {
            session.save(user);
            return user;
        });
    }

    /**
     * 对密码进行加密
     * @param password 密码
     * @return String
     */
    private static String encodePassword(String password) {
        password = password.trim();
        password = TextUtil.getMD5(password);

        return TextUtil.encodeBase64(password);
    }

    /**
     * 更新用户信息到数据库
     * @param user User
     * @return User
     */
    public static User update(User user) {
        return Hib.query(session -> {
            session.saveOrUpdate(user);
            return user;
        });
    }
}
